﻿#include "InfomationCurve2DBasical.h"
#include <QDomElement>
#include <QDomDocument>
#include <QDomAttr>
#include "DataModelPost.h"
#include "TextFileParser.h"
#include "Graph2DWindowBase.h"
#include "MainWindowSignalHandler.h"
#include "DataManager/WindowTotalData.h"
#include "DataManager/ProjectTreeData.h"

namespace pst
{
    bool InfomationCurve2DBasical::getCommonData(
        const QList<Info2DPointer>& dataList,
        Info2DPointer& commonInfo)
    {
        if (dataList.isEmpty())
        {
            // TODO 警告
            return false;
        }
        if (dataList.size() == 1)
        {
            commonInfo = dataList[0];
            return true;
        }

        commonInfo->setIsMuti(true);
        // 有多个曲线被选择->只判断 扫描参数（变量轴），DB和归一化。
        //  固定值和value列，直接置空
        // InfomationCurve2DBasical temp;
        bool hasCommonScanParameter = true;
        // TODO 不应该使用下标，同一个扫描参数在不同文件中下标可能不同, 应该改为名字？
        auto scanParameterIndex = dataList[0]->getScanParameterIndex();
        // auto OtherkeySet = dataList[0].getOtherKeyData().toList().toSet();//顺序可能有不同
        // bool isValueIndexSame{ true };
        // auto valueIndex = dataList[0].getValueIndex();

        // bool isAllOtherKeySame = true;

        // 以第一个为比较基准
        int scanIndex0 = dataList[0]->getScanParameterIndex();
        auto reader0 = dataList[0]->getReader();
        QVector<QString> keyNameList0 = reader0->getEachColNameOfKey();
        QString scanName0 = keyNameList0[dataList[0]->getScanParameterIndex()];

        int isAllNormalizedTrueCount = 0;
        int isAllNirmalized = true;

        int isAllDBTrueCount = 0;
        int isAllDB = true;

        // 获取dataSource是否相同
        QString dataSource = dataList[0]->getDataSources();
        bool isSameDataSource = true;
        for (const auto& i : dataList)
        {
            if (i->getDataSources() != dataSource)
            {
                isSameDataSource = false;
                break;
            }
        }
        if (isSameDataSource)
        {
            commonInfo->setDataSources(dataSource);
        }
        else
        {
            commonInfo->setDataSources("");
        }

        QList<QVector<QString>> AllkeyNameList;
        for (const auto& i : dataList)
        {
            // TODO 提取共同的扫描参数？
            int scanIndex = i->getScanParameterIndex();
            auto reader = i->getReader();
            if (scanIndex < 0)
            {
                // TODO 警告 正常是不会出现的
                return false;
            }
            if (reader == nullptr)
            {
                // TODO 警告 InfomationCurve2DBasical类必须是读了文件并添加后才会使用，必须含有reader
                return false;
            }
            QVector<QString> keyNameList = reader->getEachColNameOfKey();
            AllkeyNameList.append(keyNameList);

            if (i->getIsNormalized() == true)
            {
                isAllNormalizedTrueCount++;
            }
            if (i->getIsDB() == true)
            {
                isAllDBTrueCount++;
            }

            if (i->getIsNewData())
            {
                commonInfo->setIsNewData(true);
            }

            if (i->getIsOnlyShow())
            {
                commonInfo->setIsOnlyShow(true);
            }
        }

        /// 扫描参数
        // 有公共的key,并且扫描参数一致（与第一个一致）
        QList<QString> commonKeyNameList = findCommonStrings(AllkeyNameList);
        if (commonKeyNameList.contains(scanName0))
        {
            commonInfo->setCommonFixedNames(commonKeyNameList);
            // 使用第一个曲线的信息（commonInfo的reader只用于将扫描参数下标转为名字）
            commonInfo->setScanParameterIndex(scanIndex0);
            commonInfo->setReader(reader0);
        }
        else
        {
            commonInfo->setScanParameterIndex(-1);
        }

        /// 固定值 清空
        commonInfo->setOtherKeyData(QVector<double>());
        commonInfo->setValueIndex(-1);

        if (isAllNormalizedTrueCount == dataList.size())
        {
            isAllNirmalized = 1;
        }
        else if (isAllNormalizedTrueCount == 0)
        {
            isAllNirmalized = 0;
        }
        else
        {
            isAllNirmalized = -1;
        }

        if (isAllDBTrueCount == dataList.size())
        {
            isAllDB = 1;
        }
        else if (isAllDBTrueCount == 0)
        {
            isAllDB = 0;
        }
        else
        {
            isAllDB = -1;
        }

        // temp.setHasCommonScanParameter(hasCommonScanParameter);
        // temp.setIsAllOtherKeySame(isAllOtherKeySame);
        // temp.setValueIndexSame(isValueIndexSame);
        commonInfo->setIsNormalized(isAllNirmalized);
        commonInfo->setIsDB(isAllDB);
        // if (hasCommonScanParameter) //只有在有扫描参数相同的情况下才应该使用相同的扫描参数
        //{
        //     temp.setScanParameterIndex(dataList[0].getScanParameterIndex());
        // }
        // if (isAllOtherKeySame) //只有在其他Key全部相同的情况下才应该使用
        //{
        //     temp.setOtherKeyData(temp.getOtherKeyData());
        // }
        // if (isValueIndexSame) //只有在valueIndex相同的情况下才应该使用
        //{
        //     temp.setValueIndex(valueIndex);
        // }
        return true;
    }

    QDomElement& InfomationCurve2DBasical::writeToProjectFile(QDomDocument* doc, QDomElement* element, GraphType graphType, bool isdiso)
    {
        QDomElement _InfomationCurve2DBasicalRoot = doc->createElement("InfomationCurve2DBasical");
        QDomAttr idattr = doc->createAttribute("InfoID");
        idattr.setValue(QString::number(m_informationID));
        _InfomationCurve2DBasicalRoot.setAttributeNode(idattr);

        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "IsCurveVisible", QString::number(m_isCurveVisible));
        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "LineChartCurveEditParameters", m_lineChartCurveEditParameters);
        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "IsMutiCurve", QString::number(m_isMuti));
        auto _oriDataX = GlobalHelperInstance->convertQPairQStringQVectorDoubleToQString(m_x);
        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "OriDataX", _oriDataX);
        auto _oriDataY = GlobalHelperInstance->convertQPairQStringQVectorDoubleToQString(m_y);
        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "OriDataY", _oriDataY);
        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "ScanParaName", m_scanParaName);
        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "SecondScanParaName", m_secondScanParaName);
        if (m_addedGraph != nullptr)
            GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "AddedGraphID", QString::number(m_addedGraph->getWindowUniversalID()));
        //m_curveLineAddress是一个地址，无法存储,将图中曲线的点数据(m_x,m_y)保存到xml，readFromProjectFile时读取出来
        m_reader->writeToProjectFile(doc, &_InfomationCurve2DBasicalRoot, isdiso);
        //readFromProjectFile读取reader的时候用projectTreeItem到mainwindow的m_txtReader中可以找到对应指针，然后读取数据

        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "ScanParaIndexInfo", QString::number(m_scanParaIndex));
        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "SecondScanParaIndexInfo", QString::number(m_secondScanParaIndex));
        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "CommonFixedNames", m_commonFixedNames.join(","));
        auto _otherKeyDataStr = GlobalHelperInstance->convertQVectorDoubleToQString(m_otherKeyData);
        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "OtherKeyData", _otherKeyDataStr);
        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "ValueIndex", QString::number(m_valueIndex));
        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "ValueComponent", QString::number(m_valueComponent));
        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "IsNormalized", QString::number(m_isNormalized));
        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "IsDB", QString::number(m_isDB));
        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "IsDBState", QString::number(m_isDBState));
        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "GraphType", QString::number(static_cast<int>(m_graphType)));
        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "IsOnlyShow", QString::number(m_isOnlyShow));
        auto _animationDataStr = GlobalHelperInstance->convertQVectorArrayQVectorDoubleToQString(m_animationDataList);
        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "AnimationDataList", _animationDataStr);
        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "CurrentAnimationIndex", QString::number(m_currentAnimationIndex));
        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "EnableMathematicalOperations", QString::number(m_enableMathematicalOperations));
        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "CalculationFormula", m_calculationFormula);
        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "CurveName", m_curveName);
        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "IsImport", QString::number(m_isImport));
        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "GeometryFileName", m_geometryFileName.join(","));
        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "DataSources", m_dataSources);
        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "StandardCurveParserFileName", m_standardCurveParserFileName);
        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "FieldType", QString::number(m_fieldType));
        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "Unit", m_unit);
        auto _VarValueListStr = GlobalHelperInstance->convertQListDoubleToQString(m_VarValueList);
        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "VarValueList", _VarValueListStr);
        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "LastFrameIndexBeforeExportAnimation", QString::number(m_lastFrameIndexBeforeExportAnimation));
        int _itemID = -1;
        if (m_projectTreeSourceItem != nullptr)
        {
            if (!m_projectTreeSourceItem->data(Qt::UserRole + 10).isNull())
                _itemID = m_projectTreeSourceItem->data(Qt::UserRole + 10).toInt();
        }
        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "ProjectTreeSourceItem", QString::number(_itemID));

        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "IsNewData", QString::number(m_isNewData));
        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "XAxisType", QString::number(m_xAxisType));
        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "XAxisUnit", m_xAxisUnit);
        auto _yAxisUnit = GlobalHelperInstance->convertTupleToIntIntQStringToQString(m_yAxisUnit);
        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "YAxisUnit", _yAxisUnit);
        GlobalHelperInstance->createDomElement(doc, &_InfomationCurve2DBasicalRoot, "IsFromStandardFile", QString::number(m_isFromStandardFile));

        element->appendChild(_InfomationCurve2DBasicalRoot);
        if (m_curveSettingData != nullptr)
            m_curveSettingData->writeToProjectFile(doc, &_InfomationCurve2DBasicalRoot, isdiso);

        return _InfomationCurve2DBasicalRoot;
    }

    void InfomationCurve2DBasical::readFromProjectFile(QDomElement* element, GraphType graphType, bool isdiso)
    {
        int infoID = element->attribute("InfoID").toInt();
        m_informationID = infoID;

        auto _IsCurveVisibleNodeList = element->elementsByTagName("IsCurveVisible");
        m_isCurveVisible = (bool)_IsCurveVisibleNodeList.item(0).toElement().text().toInt();
        auto _LineChartCurveEditParametersNodeList = element->elementsByTagName("LineChartCurveEditParameters");
        m_lineChartCurveEditParameters = _LineChartCurveEditParametersNodeList.item(0).toElement().text();
        auto _IsMutiCurveNodeList = element->elementsByTagName("IsMutiCurve");
        m_isMuti = (bool)_IsMutiCurveNodeList.item(0).toElement().text().toInt();
        auto _oriDataXNodeList = element->elementsByTagName("OriDataX");
        m_x = GlobalHelperInstance->convertQStringToQPairQStringQVectorDouble(_oriDataXNodeList.item(0).toElement().text());
        auto _oriDataYNodeList = element->elementsByTagName("OriDataY");
        m_y = GlobalHelperInstance->convertQStringToQPairQStringQVectorDouble(_oriDataYNodeList.item(0).toElement().text());
        auto _ScanParaNameNodeList = element->elementsByTagName("ScanParaName");
        m_scanParaName = _ScanParaNameNodeList.item(0).toElement().text();
        auto _SecondScanParaNameNodeList = element->elementsByTagName("SecondScanParaName");
        m_secondScanParaName = _SecondScanParaNameNodeList.item(0).toElement().text();
        auto _AddedGraphIDNodeList = element->elementsByTagName("AddedGraphID");
        auto _AddedGraphID = _AddedGraphIDNodeList.item(0).toElement().text().toInt();
        m_addedGraph = WindowTotalDataInstance->getGraph2DWindowByID(_AddedGraphID);
        auto _standardCurveParserFileNameNodeList = element->elementsByTagName("StandardCurveParserFileName");
        m_standardCurveParserFileName = _standardCurveParserFileNameNodeList.item(0).toElement().text();
        //先读Item
        auto _ProjectTreeSourceItemNodeList = element->elementsByTagName("ProjectTreeSourceItem");
        auto _itemID = _ProjectTreeSourceItemNodeList.item(0).toElement().text().toInt();
        m_projectTreeSourceItem = ProjectTreeDataInstance->getProjectTreeItemByID(_itemID);
        if (m_projectTreeSourceItem)
            m_reader = MainWindowSignalHandlerInstance->getTextFileParserByProjectTreeItem(_itemID);
        else
        {
            //用m_dataSources去mainwindow获取m_reader
            m_reader = MainWindowSignalHandlerInstance->getTextFileParserByDataSourceByOpenProject(m_standardCurveParserFileName);
            if (m_reader == nullptr)
                return;
        }
        auto _TextFileParserEle = element->elementsByTagName("TextFileParser");
        m_reader->readFromProjectFile(&_TextFileParserEle, isdiso);

        auto _ScanParaIndexNodeList = element->elementsByTagName("ScanParaIndexInfo");
        m_scanParaIndex = _ScanParaIndexNodeList.item(0).toElement().text().toInt();
        auto _SecondScanParaIndexNodeList = element->elementsByTagName("SecondScanParaIndexInfo");
        m_secondScanParaIndex = _SecondScanParaIndexNodeList.item(0).toElement().text().toInt();
        auto _CommonFixedNamesNodeList = element->elementsByTagName("CommonFixedNames");
        m_commonFixedNames = _CommonFixedNamesNodeList.item(0).toElement().text().split(",");
        auto _OtherKeyDataNodeList = element->elementsByTagName("OtherKeyData");
        m_otherKeyData = GlobalHelperInstance->convertQStringToQVectorDouble(_OtherKeyDataNodeList.item(0).toElement().text());
        auto _ValueIndexNodeList = element->elementsByTagName("ValueIndex");
        m_valueIndex = _ValueIndexNodeList.item(0).toElement().text().toInt();
        auto _ValueComponentNodeList = element->elementsByTagName("ValueComponent");
        m_valueComponent = _ValueComponentNodeList.item(0).toElement().text().toInt();
        auto _IsNormalizedNodeList = element->elementsByTagName("IsNormalized");
        m_isNormalized = (bool)_IsNormalizedNodeList.item(0).toElement().text().toInt();
        auto _IsDBNodeList = element->elementsByTagName("IsDB");
        m_isDB = _IsDBNodeList.item(0).toElement().text().toInt();
        auto _IsDBStateNodeList = element->elementsByTagName("IsDBState");
        m_isDBState = _IsDBStateNodeList.item(0).toElement().text().toInt();

        auto _GraphTypeNodeList = element->elementsByTagName("GraphType");
        m_graphType = (GraphType)_GraphTypeNodeList.item(0).toElement().text().toInt();

        auto _IsOnlyShowNodeList = element->elementsByTagName("IsOnlyShow");
        m_isOnlyShow = (bool)_IsOnlyShowNodeList.item(0).toElement().text().toInt();
        auto _AnimationDataListNodeList = element->elementsByTagName("AnimationDataList");
        m_animationDataList = GlobalHelperInstance->convertQStringToQVectorArrayQVectorDouble(_AnimationDataListNodeList.item(0).toElement().text());
        auto _CurrentAnimationIndexNodeList = element->elementsByTagName("CurrentAnimationIndex");
        m_currentAnimationIndex = _CurrentAnimationIndexNodeList.item(0).toElement().text().toInt();
        auto _EnableMathematicalOperationsNodeList = element->elementsByTagName("EnableMathematicalOperations");
        m_enableMathematicalOperations = (bool)_EnableMathematicalOperationsNodeList.item(0).toElement().text().toInt();
        auto _CalculationFormulaNodeList = element->elementsByTagName("CalculationFormula");
        m_calculationFormula = _CalculationFormulaNodeList.item(0).toElement().text();
        auto _CurveNameNodeList = element->elementsByTagName("CurveName");
        m_curveName = _CurveNameNodeList.item(0).toElement().text();
        auto _IsImportNodeList = element->elementsByTagName("IsImport");
        m_isImport = (bool)_IsImportNodeList.item(0).toElement().text().toInt();
        auto _GeometryFileNameNodeList = element->elementsByTagName("GeometryFileName");
        m_geometryFileName = _GeometryFileNameNodeList.item(0).toElement().text().split(",");
        auto _DataSourcesNodeList = element->elementsByTagName("DataSources");
        m_dataSources = _DataSourcesNodeList.item(0).toElement().text();
        auto _FieldTypeNodeList = element->elementsByTagName("FieldType");
        m_fieldType = _FieldTypeNodeList.item(0).toElement().text().toInt();
        auto _UnitNodeList = element->elementsByTagName("Unit");
        m_unit = _UnitNodeList.item(0).toElement().text();
        auto _VarValueListNodeList = element->elementsByTagName("VarValueList");
        m_VarValueList = GlobalHelperInstance->convertQStringToQListDouble(_VarValueListNodeList.item(0).toElement().text());
        auto _LastFrameIndexBeforeExportAnimationNodeList = element->elementsByTagName("LastFrameIndexBeforeExportAnimation");
        m_lastFrameIndexBeforeExportAnimation = _LastFrameIndexBeforeExportAnimationNodeList.item(0).toElement().text().toInt();

        auto _IsNewDataNodeList = element->elementsByTagName("IsNewData");
        m_isNewData = (bool)_IsNewDataNodeList.item(0).toElement().text().toInt();
        auto _XAxisTypeNodeList = element->elementsByTagName("XAxisType");
        m_xAxisType = _XAxisTypeNodeList.item(0).toElement().text().toInt();
        auto _XAxisUnitNodeList = element->elementsByTagName("XAxisUnit");
        m_xAxisUnit = _XAxisUnitNodeList.item(0).toElement().text();
        auto _YAxisUnitNodeList = element->elementsByTagName("YAxisUnit");
        auto _YAxisUnit = _YAxisUnitNodeList.item(0).toElement().text();
        m_yAxisUnit = GlobalHelperInstance->convertQStringToTupleToIntIntQString(_YAxisUnit);

        auto _IsFromStandardFile = element->elementsByTagName("IsFromStandardFile");
        m_isFromStandardFile = (bool)_IsFromStandardFile.item(0).toElement().text().toInt();

        auto _Style2D_DataPropertyNodeList = element->elementsByTagName("Style2D_DataProperty");
        if (graphType != GraphType::TwoDHeatMap)
        {
            m_curveSettingData = new Style2D_DataProperty(m_addedGraph);
            m_curveSettingData->readFromProjectFile(&_Style2D_DataPropertyNodeList.at(0).toElement(), isdiso);
        }

    }
} // namespace pst
